package li.brauch.semesterarbeit.radio.views;

import java.util.ArrayList;
import java.util.List;

import li.brauch.semesterarbeit.radio.model.Track;
import li.brauch.semesterarbeit.radio.views.util.ColorStore;
import li.brauch.semesterarbeit.radio.views.util.FontStore;
import li.brauch.semesterarbeit.radio.views.util.ImageStore;
import li.brauch.semesterarbeit.radio.views.widgets.ProgressBar;
import li.brauch.semesterarbeit.radio.views.widgets.VolumeSlider;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;

public class PlayerPanel extends Composite {

	private List<PlayerPanelListener> listeners = new ArrayList<PlayerPanelListener>();
	
	private Label playButton;
	private Label stopButton;
	private Label skipButton;
	private Label buyButton;
	private Label loveButton;
	private Label banButton;
	private Label muteButton;
	
	private Label cover;
	
	private VolumeSlider volume;
	
	private Label trackState;
	private Label trackEnd;
	
	private ProgressBar trackProgress;
	
	private Label trackName;
	private Label trackAlbum;
	
	private boolean mute = false;
	private boolean pause = false;
	
	public PlayerPanel(Composite parent) {
		super(parent, SWT.NONE);
		
		GridLayout layout = new GridLayout();
		layout.numColumns = 8;
		layout.makeColumnsEqualWidth = false;
		setLayout(layout);
		setBackground(ColorStore.BACKGROUND);
		
		GridData layoutdata = new GridData();
		layoutdata.horizontalAlignment = GridData.FILL;
		layoutdata.verticalAlignment = GridData.FILL;
		layoutdata.grabExcessHorizontalSpace = true;
		layoutdata.grabExcessVerticalSpace = true;
		setLayoutData(layoutdata);
		
		playButton = new Label(this, SWT.NONE);
		{
			playButton.setImage(ImageStore.PAUSE);		
			playButton.setBackground(ColorStore.BACKGROUND);
			layoutdata = new GridData();		
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.CENTER;
			layoutdata.grabExcessVerticalSpace = false;		
			playButton.setLayoutData(layoutdata);
			
			playButton.addListener(SWT.MouseEnter, new Listener() {
			      public void handleEvent(Event e) {
			    	  if (pause)
			    		  playButton.setImage(ImageStore.PLAY_ROLLOVER);
			    	  else
			    		  playButton.setImage(ImageStore.PAUSE_ROLLOVER);
			      }
			    });
			playButton.addListener(SWT.MouseExit, new Listener() {
			      public void handleEvent(Event e) {
			    	  if (pause)
			    		  playButton.setImage(ImageStore.PLAY);
			    	  else
			    		  playButton.setImage(ImageStore.PAUSE);
			      }
			    });
			
			playButton.addListener(SWT.MouseDown, new Listener() {
			      public void handleEvent(Event e) {
			    	  if (pause)
			    		  playButton.setImage(ImageStore.PLAY_CLICK);
			    	  else
			    		  playButton.setImage(ImageStore.PAUSE_CLICK);
			      }
			    });
			playButton.addListener(SWT.MouseUp, new Listener() {
			      public void handleEvent(Event e) {
			    	  
			    	  pause = !pause;
			    	  
			    	  if (pause) {
			    		  playButton.setImage(ImageStore.PLAY_ROLLOVER);
			    		  notifyPauseClicked();
			    		  
			    	  } else {
			    		  playButton.setImage(ImageStore.PAUSE_ROLLOVER);
			    		  notifyResumeClicked();
			    	  }
			    	  
			      }
			    });
		}
		
		stopButton = new Label(this, SWT.NONE);
		{
			stopButton.setImage(ImageStore.STOP);		
			stopButton.setBackground(ColorStore.BACKGROUND);
			layoutdata = new GridData();		
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.CENTER;
			layoutdata.grabExcessVerticalSpace = false;		
			stopButton.setLayoutData(layoutdata);
			
			stopButton.addListener(SWT.MouseEnter, new Listener() {
			      public void handleEvent(Event e) {
			    	  stopButton.setImage(ImageStore.STOP_ROLLOVER);
			      }
			    });
			stopButton.addListener(SWT.MouseExit, new Listener() {
			      public void handleEvent(Event e) {
			    	  stopButton.setImage(ImageStore.STOP);
			      }
			    });
			
			stopButton.addListener(SWT.MouseDown, new Listener() {
			      public void handleEvent(Event e) {
			    	  stopButton.setImage(ImageStore.STOP_CLICK);		    	  
			      }
			    });
			stopButton.addListener(SWT.MouseUp, new Listener() {
			      public void handleEvent(Event e) {
			    	  stopButton.setImage(ImageStore.STOP_ROLLOVER);
			    	  
			    	  notifyStopClicked();
			      }
			    });
		}
		
		skipButton = new Label(this, SWT.NONE);
		{
			skipButton.setImage(ImageStore.SKIP);		
			skipButton.setBackground(ColorStore.BACKGROUND);
			layoutdata = new GridData();		
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.CENTER;
			layoutdata.grabExcessVerticalSpace = false;		
			skipButton.setLayoutData(layoutdata);
			
			skipButton.addListener(SWT.MouseEnter, new Listener() {
			      public void handleEvent(Event e) {
			    	  skipButton.setImage(ImageStore.SKIP_ROLLOVER);
			      }
			    });
			skipButton.addListener(SWT.MouseExit, new Listener() {
			      public void handleEvent(Event e) {
			    	  skipButton.setImage(ImageStore.SKIP);
			      }
			    });
			
			skipButton.addListener(SWT.MouseDown, new Listener() {
			      public void handleEvent(Event e) {
			    	  skipButton.setImage(ImageStore.SKIP_CLICK);		    	  
			      }
			    });
			skipButton.addListener(SWT.MouseUp, new Listener() {
			      public void handleEvent(Event e) {
			    	  skipButton.setImage(ImageStore.SKIP_ROLLOVER);
			    	  
			    	  notifySkipClicked();
			      }
			    });
		}
		
		muteButton = new Label(this, SWT.NONE);
		{
			muteButton.setImage(ImageStore.AUDIBLE);		
			muteButton.setBackground(ColorStore.BACKGROUND);
			layoutdata = new GridData();		
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.CENTER;
			layoutdata.grabExcessVerticalSpace = false;		
			muteButton.setLayoutData(layoutdata);
			
			muteButton.addListener(SWT.MouseEnter, new Listener() {
			      public void handleEvent(Event e) {
			    	  if (mute)
			    		  muteButton.setImage(ImageStore.MUTE_ROLLOVER);
			    	  else
			    		  muteButton.setImage(ImageStore.AUDIBLE_ROLLOVER);
			      }
			    });
			muteButton.addListener(SWT.MouseExit, new Listener() {
			      public void handleEvent(Event e) {
			    	  if (mute)
			    		  muteButton.setImage(ImageStore.MUTE);
			    	  else
			    		  muteButton.setImage(ImageStore.AUDIBLE);
			      }
			    });
			
			muteButton.addListener(SWT.MouseDown, new Listener() {
			      public void handleEvent(Event e) {
			    	  if (mute)
			    		  muteButton.setImage(ImageStore.MUTE_CLICK);
			    	  else
			    		  muteButton.setImage(ImageStore.AUDIBLE_CLICK);
			      }
			    });
			muteButton.addListener(SWT.MouseUp, new Listener() {
			      public void handleEvent(Event e) {
			    	  
			    	  mute = !mute;
			    	  
			    	  if (mute)
			    		  muteButton.setImage(ImageStore.MUTE_ROLLOVER);			    		 
			    	  else
			    		  muteButton.setImage(ImageStore.AUDIBLE_ROLLOVER);					    	
			    	  
			    	  notifyMuteClicked();
			      }
			    });
			
			muteButton.addListener(SWT.Selection, new Listener() {
				public void handleEvent(Event event) {
					System.out.println("clicked");				
				}
			});
		}
		
		volume = new VolumeSlider (this, SWT.NONE);
		{
			volume.setBackground(ColorStore.BACKGROUND);
			volume.setForeground(ColorStore.FOREGROUND);
			volume.setRollover(ColorStore.ROLLOVER);
			volume.setValue(50);
			volume.setSize(100,12);
			layoutdata = new GridData();	
			layoutdata.horizontalSpan = 3;
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.CENTER;
			layoutdata.grabExcessVerticalSpace = false;		
			volume.setLayoutData(layoutdata);
			
			volume.addListener(SWT.Selection, new Listener() {
				
				public void handleEvent(Event event) {
					
					notifyVolumeChanged((Integer) event.data);
				}
			});
		}
		
		cover = new Label(this, SWT.NONE);
		{
			cover.setImage(ImageStore.NO_COVER);
			cover.setBackground(ColorStore.BACKGROUND);
			layoutdata = new GridData();		
			layoutdata.verticalSpan = 5;
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessHorizontalSpace = true;
			layoutdata.verticalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessVerticalSpace = true;		
			cover.setLayoutData(layoutdata);
		}
		
		trackState = new Label(this, SWT.NONE);
		{
			trackState.setText("0:00");
			trackState.setBackground(ColorStore.BACKGROUND);
			trackState.setForeground(ColorStore.FOREGROUND);
			layoutdata = new GridData();	
			layoutdata.horizontalSpan = 2;
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.END;
			layoutdata.grabExcessVerticalSpace = false;		
			trackState.setLayoutData(layoutdata);
		} 
		
		trackEnd = new Label(this, SWT.NONE);
		{
			trackEnd.setText("5:25");
			trackEnd.setBackground(ColorStore.BACKGROUND);
			trackEnd.setForeground(ColorStore.FOREGROUND);
			layoutdata = new GridData();	
			layoutdata.horizontalSpan = 2;
			layoutdata.horizontalAlignment = GridData.END;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.END;
			layoutdata.grabExcessVerticalSpace = false;		
			trackEnd.setLayoutData(layoutdata);
		} 
		
		loveButton = new Label(this, SWT.NONE);
		{
			loveButton.setImage(ImageStore.LOVE);		
			loveButton.setBackground(ColorStore.BACKGROUND);
			layoutdata = new GridData();
			layoutdata.verticalSpan = 2;
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.CENTER;
			layoutdata.grabExcessVerticalSpace = false;		
			loveButton.setLayoutData(layoutdata);
			
			loveButton.addListener(SWT.MouseEnter, new Listener() {
			      public void handleEvent(Event e) {
			    	  loveButton.setImage(ImageStore.LOVE_ROLLOVER);
			      }
			    });
			loveButton.addListener(SWT.MouseExit, new Listener() {
			      public void handleEvent(Event e) {
			    	  loveButton.setImage(ImageStore.LOVE);
			      }
			    });
			
			loveButton.addListener(SWT.MouseDown, new Listener() {
			      public void handleEvent(Event e) {
			    	  loveButton.setImage(ImageStore.LOVE_CLICK);		    	  
			      }
			    });
			loveButton.addListener(SWT.MouseUp, new Listener() {
			      public void handleEvent(Event e) {
			    	  loveButton.setImage(ImageStore.LOVE_ROLLOVER);
			    	  notifyLoveClicked();
			      }
			    });
		}
		
		banButton = new Label(this, SWT.NONE);
		{
			banButton.setImage(ImageStore.BAN);		
			banButton.setBackground(ColorStore.BACKGROUND);
			layoutdata = new GridData();	
			layoutdata.verticalSpan = 2;
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.CENTER;
			layoutdata.grabExcessVerticalSpace = false;		
			banButton.setLayoutData(layoutdata);
			
			banButton.addListener(SWT.MouseEnter, new Listener() {
			      public void handleEvent(Event e) {
			    	  banButton.setImage(ImageStore.BAN_ROLLOVER);
			      }
			    });
			banButton.addListener(SWT.MouseExit, new Listener() {
			      public void handleEvent(Event e) {
			    	  banButton.setImage(ImageStore.BAN);
			      }
			    });
			
			banButton.addListener(SWT.MouseDown, new Listener() {
			      public void handleEvent(Event e) {
			    	  banButton.setImage(ImageStore.BAN_CLICK);		    	  
			      }
			    });
			banButton.addListener(SWT.MouseUp, new Listener() {
			      public void handleEvent(Event e) {
			    	  banButton.setImage(ImageStore.BAN_ROLLOVER);
			    	  notifyBanClicked();
			      }
			    });
		}
		
		buyButton = new Label(this, SWT.NONE);
		{
			buyButton.setImage(ImageStore.BUY);		
			buyButton.setBackground(ColorStore.BACKGROUND);
			layoutdata = new GridData();		
			layoutdata.verticalSpan = 2;
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.CENTER;
			layoutdata.grabExcessVerticalSpace = false;		
			buyButton.setLayoutData(layoutdata);
			
			buyButton.addListener(SWT.MouseEnter, new Listener() {
			      public void handleEvent(Event e) {
			    	  buyButton.setImage(ImageStore.BUY_ROLLOVER);
			      }
			    });
			buyButton.addListener(SWT.MouseExit, new Listener() {
			      public void handleEvent(Event e) {
			    	  buyButton.setImage(ImageStore.BUY);
			      }
			    });
			
			buyButton.addListener(SWT.MouseDown, new Listener() {
			      public void handleEvent(Event e) {
			    	  buyButton.setImage(ImageStore.BUY_CLICK);		    	  
			      }
			    });
			buyButton.addListener(SWT.MouseUp, new Listener() {
			      public void handleEvent(Event e) {
			    	  buyButton.setImage(ImageStore.BUY_ROLLOVER);
			    	  notifyBuyClicked();
			      }
			    });
		}
		
		trackProgress = new ProgressBar(this, SWT.NONE);
		{
			trackProgress.setBackground(ColorStore.BACKGROUND);
			trackProgress.setForeground(ColorStore.FOREGROUND);
			trackProgress.setMaximum(50);
			trackProgress.setValue(25);
			trackProgress.setSize(100, 8);
			layoutdata = new GridData();	
			layoutdata.horizontalSpan = 4;
			layoutdata.horizontalAlignment = GridData.FILL;
			layoutdata.grabExcessHorizontalSpace = false;
			layoutdata.verticalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessVerticalSpace = false;		
			trackProgress.setLayoutData(layoutdata);
		}
		
		trackName = new Label(this, SWT.NONE);
		{	
			trackName.setBackground(ColorStore.BACKGROUND);
			trackName.setFont(FontStore.TRACK_NAME);
			trackName.setForeground(ColorStore.FOREGROUND);
			layoutdata = new GridData();	
			layoutdata.horizontalSpan = 7;
			layoutdata.horizontalAlignment = GridData.BEGINNING;
			layoutdata.widthHint = 300;
			layoutdata.grabExcessHorizontalSpace = true;
			layoutdata.verticalAlignment = GridData.FILL;
			layoutdata.grabExcessVerticalSpace = false;		
			trackName.setLayoutData(layoutdata);
		}
		
		trackAlbum = new Label(this, SWT.NONE);
		{			
			trackAlbum.setBackground(ColorStore.BACKGROUND);
			trackAlbum.setFont(FontStore.TRACK_ALBUM);
			trackAlbum.setForeground(ColorStore.FOREGROUND);
			layoutdata = new GridData();	
			layoutdata.horizontalSpan = 7;
			layoutdata.horizontalAlignment = GridData.FILL;
			layoutdata.widthHint = 300;
			layoutdata.grabExcessHorizontalSpace = true;
			layoutdata.verticalAlignment = GridData.BEGINNING;
			layoutdata.grabExcessVerticalSpace = false;		
			trackAlbum.setLayoutData(layoutdata);
		}
	}
	
	public void addPlayerPanelListener(PlayerPanelListener listener) {
		if (!listeners.contains(listener))
			listeners.add(listener);
	}
	
	public void removePlayerPanelListener(PlayerPanelListener listener) {
		if (listeners.contains(listener))
			listeners.remove(listener);
	}
	
	public void setTrack(final Track track) {
		
		// Update this inside UI thread
		getDisplay().asyncExec(new Runnable() {
				
				public void run() {
					Image oldCover = cover.getImage();
					if (track.getCover() != null) {
						
						if (oldCover != ImageStore.NO_COVER) {
							cover.getImage().dispose();
						}
						
						cover.setImage(ImageStore.createImage(track.getCover()));
					
					} else {
						if (oldCover != ImageStore.NO_COVER) {
							cover.getImage().dispose();
							cover.setImage(ImageStore.NO_COVER);
						}
					}
					
					trackName.setText(track.getArtist() + " - " + track.getTitle());
					trackAlbum.setText(track.getAlbum());
					trackProgress.setMaximum(track.getDuration());
					trackProgress.setMinimum(0);
					trackProgress.setValue(0);
					
					int tmp = Math.round(track.getDuration() / 1000);
					
					final int m = tmp / 60;
					final int s = tmp % 60;
					
					trackEnd.setText(m + ":" + (s < 10 ? "0" : "") + s);
					trackState.setText("0:00");
				}
		});
	}
	
	public void updateTrackPosition(final long position) {
		
		long tmp = position / 1000;
		final long m = tmp / 60;
		final long s = tmp % 60;
		
		// Update this by the UI thread	
		Display.getDefault().asyncExec(new Runnable() {
			
			public void run() {
				
				if (!trackProgress.isDisposed())
					trackProgress.setValue(position);
				if (!trackState.isDisposed())
					trackState.setText(m + ":" + (s < 10 ? "0" : "") + s);
			}
		});
	}
	
	private void notifyStopClicked() {
		
		for (PlayerPanelListener listener : listeners) {
			listener.stopClicked();
		}	
	}
	
	private void notifyPauseClicked() {
		
		for (PlayerPanelListener listener : listeners) {
			listener.pauseClicked();
		}
	}
	
	private void notifyResumeClicked() {
		
		for (PlayerPanelListener listener : listeners) {				
			listener.resumeClicked();
		}	
	}
	
	private void notifySkipClicked() {
		
		for (PlayerPanelListener listener : listeners) {
			listener.skipClicked();
		}			
	}
	
	private void notifyLoveClicked() {
		
		for (PlayerPanelListener listener : listeners) {
			listener.loveClicked();	
		}
	}
	
	private void notifyBanClicked() {
		
		for (PlayerPanelListener listener : listeners) {
			listener.banClicked();
		}	
	}
	
	private void notifyMuteClicked() {
		
		for (PlayerPanelListener listener : listeners) {
			listener.muteClicked();		
		}
	}
	
	private void notifyVolumeChanged(final int volume) {
		
		for (PlayerPanelListener listener : listeners) {			
			listener.volumeChanged(volume);
		}
	}
	
	private void notifyBuyClicked() {
		
		for (PlayerPanelListener listener : listeners) {
			listener.buyClicked();
		}
	}
}
